package com.mxpio.erp.inventory.policy.impl;

import com.mxpio.erp.common.ModuleUtils;
import com.mxpio.erp.common.enums.CommonEnums;
import com.mxpio.erp.common.enums.NoticeStatusEnums;
import com.mxpio.erp.common.enums.OrderEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.inventory.entity.ToNotice;
import com.mxpio.erp.common.inventory.entity.TransferOrder;
import com.mxpio.erp.common.jpa.model.Notice;
import com.mxpio.erp.common.jpa.model.NoticeLine;
import com.mxpio.erp.common.jpa.model.Order;
import com.mxpio.erp.common.order.policy.AbstractBizOrderPolicy;
import com.mxpio.erp.common.order.policy.OrderContext;
import com.mxpio.erp.common.technology.entity.Item;
import com.mxpio.erp.common.vo.OrderExcuteLineVo;
import com.mxpioframework.common.util.BeanReflectionUtils;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.security.util.SecurityUtils;
import org.apache.commons.collections4.CollectionUtils;

import java.util.*;

/**
 * 调拨单执行策略
 *
 */
public class DefaultToPolicy extends AbstractBizOrderPolicy {

	private List<OrderExcuteLineVo> orderExcuteVos;
	
	private String accessType;

	public DefaultToPolicy(List<OrderExcuteLineVo> orderExcuteVos) {
		this.orderExcuteVos = orderExcuteVos;
		this.accessType = "in,out";//不指定类型，一次执行，同时生成对应的调拨入/调拨出通知单
	}

	@Override
	public void execute(OrderContext context) {
	}

	@Override
	public OrderContext config(OrderContext context) {
		context.setOrderExcuteVos(orderExcuteVos);
		context.setNoticeClass(ToNotice.class);
		context.setAccessType(accessType);
		/*if(OrderEnums.AccessType.IN.getCode().equals(accessType)){
			context.setPickingType(NoticeStatusEnums.NoticeType.TO_IN.getCode());
		}else{
			context.setPickingType(NoticeStatusEnums.NoticeType.TO_OUT.getCode());
		}*/
		return context;
	}

	@Override
	public boolean beforeExecute(OrderContext context) {
		return true;
	}

	@Override
	public void afterExecute(OrderContext context) {
		//更新状态
		Order order = context.getEntity();
		if (OrderStatusEnums.OrderStatus.ORDERED.getStatusCode().equals(order.getOrderStatus())||
				OrderStatusEnums.OrderStatus.PLAN.getStatusCode().equals(order.getOrderStatus())){
			order.setOrderStatus(OrderStatusEnums.OrderStatus.PROCESSING.getStatusCode());
			order.setExecuteTime(new Date());
			order.setExecutor(SecurityUtils.getLoginUsername());
			JpaUtil.update(order);
		}
	}

	@Override
	public void apply(OrderContext context) {//覆盖AbstractBizOrderPolicy中的方法，一次执行，同时生成调拨 出和入的通知单
		if(beforeExecute(context)) {
			execute(context);
			TransferOrder order = (TransferOrder) context.getEntity();
			List<OrderExcuteLineVo> orderExcuteVos = context.getOrderExcuteVos();

			String[] accessTypes = context.getAccessType().split(",");
			for(String accessType : accessTypes){
				// 遍历执行行 生成通知单
				Map<String, Notice> noticeMap = new HashMap<>();
				Map<String,List<OrderExcuteLineVo>> voMap = new HashMap<>();
				for(OrderExcuteLineVo orderExcuteVo : orderExcuteVos) {
					Notice notice = noticeMap.get(orderExcuteVo.getWhCode() + orderExcuteVo.getInQualityControl());
					if(notice == null) {
						if(CommonEnums.YesNo.YES.getCode().equals(orderExcuteVo.getInQualityControl())&& ModuleUtils.contains("Quality")){
							notice = (Notice) BeanReflectionUtils.newInstance(context.getQualityClass());
						}else{
							notice = (Notice) BeanReflectionUtils.newInstance(context.getNoticeClass());
						}

						notice.setBizOrderNo(order.getBizNo());
						notice.setNoticeDate(new Date());
						notice.setAccessType(accessType);
						//notice.setPickingType(context.getPickingType());
						if(OrderEnums.AccessType.IN.getCode().equals(accessType)){
							notice.setPickingType(NoticeStatusEnums.NoticeType.TO_IN.getCode());
							notice.setWhCode(order.getWhCode());
						}else{
							notice.setPickingType(NoticeStatusEnums.NoticeType.TO_OUT.getCode());
							notice.setWhCode(order.getOriginWhCode());
						}
						notice.setNoticeStatus(NoticeStatusEnums.NoticeStatus.CREATE.getStatusCode());
						noticeMap.put(orderExcuteVo.getWhCode() + orderExcuteVo.getInQualityControl(), notice);
						voMap.put(orderExcuteVo.getWhCode() + orderExcuteVo.getInQualityControl(), new ArrayList<OrderExcuteLineVo>());
					}
					voMap.get(orderExcuteVo.getWhCode() + orderExcuteVo.getInQualityControl()).add(orderExcuteVo);
				}
				// 生成通知单明细
				for(Map.Entry<String,Notice> entry : noticeMap.entrySet()) {
					Notice notice = entry.getValue();
					JpaUtil.save(notice);
					int lineNo = 0;
					for(OrderExcuteLineVo vo : voMap.get(entry.getKey())) {
						lineNo++;
						NoticeLine line = notice.createLine(vo);
						line.setSubLotIndex(vo.getSubLotIndex());
						line.setLineNo(lineNo+"");
						Item item = JpaUtil.linq(Item.class).idEqual(vo.getItemCode()).findOne();
						line.setItemName(item.getItemName());
						line.setItemSpec(item.getItemSpec());
						line.setUnitCode(item.getUnitCode());
						line.setDrawingNo(item.getDrawingNo());
						JpaUtil.save(line);
					}
				}
			}
			/*if(OrderStatusEnums.OrderStatus.PLAN.getStatusCode().equals(order.getOrderStatus())||
					OrderStatusEnums.OrderStatus.ORDERED.getStatusCode().equals(order.getOrderStatus())){
				order.setOrderStatus(OrderStatusEnums.OrderStatus.PROCESSING.getStatusCode());
				JpaUtil.update(order);
			}*/
			afterExecute(context);
		} else {
			if(CollectionUtils.isEmpty(context.getErrors())) {
				context.addError("前置校验不通过");
			}
		}
	}
}
